package com.backend.demo.util;

import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import ognl.NullHandler;
import ognl.Ognl;
import ognl.OgnlException;
import ognl.OgnlRuntime;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 反射工具类
 * 
 * @author 陈兴吉
 * @date 2007-9-16
 */
public class ClassUtil {

	private static Class[][] PRIMARY = { { Boolean.class, Boolean.TYPE },
			{ Byte.class, Byte.TYPE }, { Character.class, Character.TYPE },
			{ Short.class, Short.TYPE }, { Integer.class, Integer.TYPE },
			{ Long.class, Long.TYPE }, { Float.class, Float.TYPE },
			{ Double.class, Double.TYPE }, { Void.class, Void.TYPE } };

	public static Class forName(String name) throws ClassNotFoundException {
		return getClassLoader().loadClass(name);
	}

	public static ClassLoader getClassLoader() {
		return Thread.currentThread().getContextClassLoader();
	}

	public static String getClassNameByURL(URL url) {
		return getClassNameByURLPath(url.getPath());
	}

	public static String getClassNameByURLPath(String path) {
		int jarIndex = path.indexOf("jar!/");
		if (jarIndex > 0) {
			return path.substring(jarIndex + "jar!/".length())
					.replace(".class", "").replace("/", ".");
		}

		int classesComIndex = path.indexOf("/classes/com");
		if (classesComIndex > 0) {
			return path.substring(classesComIndex + "/classes/".length())
					.replace(".class", "").replace("/", ".");
		}

		int classesCnIndex = path.indexOf("/classes/cn");
		if (classesCnIndex > 0) {
			return path.substring(classesCnIndex + "/classes/".length())
					.replace(".class", "").replace("/", ".");
		}

		int classesOrgIndex = path.indexOf("/classes/org");
		if (classesOrgIndex > 0) {
			return path.substring(classesOrgIndex + "/classes/".length())
					.replace(".class", "").replace("/", ".");
		}

		int classesIndex = path.indexOf("/classes/");
		if (classesIndex > 0) {
			return path.substring(classesIndex + "/classes/".length())
					.replace(".class", "").replace("/", ".");
		}

		int comYlinkIndexOf = path.indexOf("com/ylink/");
		if (comYlinkIndexOf > 0) {
			return path.substring(comYlinkIndexOf).replace(".class", "")
					.replace("/", ".");
		}

		int comJFastShopIndexOf = path.indexOf("com/jfastshop/");
		if (comJFastShopIndexOf > 0) {
			return path.substring(comJFastShopIndexOf).replace(".class", "")
					.replace("/", ".");
		}

		return null;
	}

	public static Class toMainClass(Class cls) {
		if (cls != null && cls.isPrimitive()) {
			for (Class[] pc : PRIMARY) {
				if (pc[1] == cls)
					return pc[0];
			}
		}
		return cls;
	}

	public static Class toPrimaryClass(Class cls) {
		if (cls == null)
			return cls;
		if (cls.isPrimitive())
			return cls;
		for (Class[] pc : PRIMARY) {
			if (pc[0] == cls)
				return pc[1];
		}
		return cls;
	}

	public static boolean isMainClass(Class cls) {
		for (Class[] pc : PRIMARY) {
			if (pc[1] == cls || pc[0] == cls)
				return true;
		}
		if (cls == String.class) {
			return true;
		}

		return false;
	}

	public static boolean isAssignFrom(Class[] cls, Class[] from) {
		if (cls == null || cls.length == 0) {
			if (from == null || from.length == 0) {
				return true;
			}
		}

		if (cls.length != from.length)
			return false;

		for (int i = 0; i < cls.length; i++) {
			if (!isAssignFrom(cls[i], from[i]))
				return false;
		}
		return true;
	}

	public static boolean isAssignFrom(Class<?> var, Class<?> value) {
		if (var == null) {
			return value == null;
		}

		if (value == null) {
			return false;
		}

		var = toMainClass(var);
		value = toMainClass(value);
		if (var.isAssignableFrom(value)) {
			return true;
		}

		return false;
	}

	public static boolean isImplementInterface(Class<?> cls,
			Class<?> interfaceClass) {
		if (cls == null || interfaceClass == null) {
			return false;
		}
		return interfaceClass.isAssignableFrom(cls);
	}

	public static boolean isExtendFrom(Class<?> cls, Class<?> from) {
		if (cls == null || from == null)
			return false;
		return from.isAssignableFrom(cls);
	}

	public static boolean isExtendFromOnce(Class<?> cls,
			Collection<Class<?>> fromClasses) {
		if (fromClasses == null) {
			return false;
		}
		for (Class<?> from : fromClasses) {
			if (isExtendFrom(cls, from)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 根据条件查找某些类中的某个方法(不包含父类的方法)
	 * 
	 * @param clazz
	 *            要进行查找的类
	 * @param methodName
	 *            方法名
	 * @return
	 */
	public static Method lookupMethod(Class<?> clazz, String methodName) {
		return lookupMethod(clazz, methodName, null, null, false);
	}

	/**
	 * 根据条件查找某些类中的某个方法(不包含父类的方法)
	 * 
	 * @param clazz
	 *            要进行查找的类
	 * @param methodName
	 *            方法名
	 * @param returnType
	 *            返回类型
	 * @return
	 */
	public static Method lookupMethod(Class<?> clazz, String methodName,
			Class<?> returnType) {
		return lookupMethod(clazz, methodName, returnType, null, false);
	}

	/**
	 * 根据条件查找某些类中的某个方法(不包含父类的方法)
	 * 
	 * @param clazz
	 *            要进行查找的类
	 * @param methodName
	 *            方法名
	 * @param returnType
	 *            返回类型
	 * @param valcls
	 *            参数的类型
	 * @return
	 */
	public static Method lookupMethod(Class<?> clazz, String methodName,
			Class<?> returnType, Class<?>[] valcls) {
		return lookupMethod(clazz, methodName, returnType, valcls, false);
	}

	/**
	 * 根据条件查找某些类中的某个方法
	 * 
	 * @param cls
	 *            要进行查找的类
	 * @param methodName
	 *            方法名
	 * @param returnType
	 *            返回类型
	 * @param valcls
	 *            参数的类型
	 * @param includeParent
	 *            是否包含所有的父类中的方法
	 * @return
	 */
	public static Method lookupMethod(Class<?> cls, String methodName,
			Class<?> returnType, Class<?>[] valcls, boolean includeParent) {
		if (cls == null || StringUtils.emptyTrimed(methodName)) {
			return null;
		}

		Method[] ms = cls.getMethods();
		if (CollectionUtils.notEmpty(ms)) {
			for (Method m : ms) {
				if (m.getName().equals(methodName)) {
					// 如果参数类型数组不为空,要进行参数类型对比
					if (valcls != null) {
						Class<?>[] pcs = m.getParameterTypes();
						if (!isAssignFrom(valcls, pcs)) {
							continue;
						}
					}
					// 如果返回类型不为空,要进行返回类型的对比
					if (returnType != null) {
						Class<?> rt = m.getReturnType();
						if (!isAssignFrom(returnType, rt)) {
							continue;
						}
					}
					return m;
				}
			}
		}

		// 如果需要查找包含父类的方法
		if (includeParent) {
			Class<?> superClazz = cls.getSuperclass();
			if (superClazz != null) {
				return lookupMethod(superClazz, methodName, returnType, valcls,
						includeParent);
			}
		}

		return null;
	}

	/**
	 * 得到某类中的属性(不包含父类中的属性,只是本类中的属性)
	 * 
	 * @param clazz
	 *            要进行查找的类
	 * @param fieldName
	 *            属性名
	 * @param fieldType
	 *            属性的类型
	 * @return
	 */
	public static Field getLocalField(Class cls, String name, Class fieldType) {
		Field[] fs = cls.getDeclaredFields();
		for (Field f : fs) {
			if (f.getName().equals(name)) {
				if (fieldType == null || isExtendFrom(f.getType(), fieldType)) {
					return f;
				}
			}
		}
		return null;
	}

	/**
	 * 得到某类中的属性(包含父类中的属性)
	 * 
	 * @param clazz
	 *            要进行查找的类
	 * @param fieldName
	 *            属性名
	 * @param fieldType
	 *            属性的类型
	 * @return
	 */
	public static Field getField(Class clazz, String fieldName, Class fieldType) {
		if (clazz == null || StringUtils.emptyTrimed(fieldName)) {
			return null;
		}

		Field f = getLocalField(clazz, fieldName, fieldType);
		if (f == null) {
			Class<?> superClazz = clazz.getSuperclass();
			if (superClazz != null) {
				return getField(superClazz, fieldName, fieldType);
			}
		}
		return f;
	}

	public static Method getMethod(Class cls, String name, Class[] valcls)
			throws Exception {
		if (cls == null) {
			return null;
		}
		Method m = lookupMethod(cls, name, null, valcls);
		if (m != null) {
			return m;
		}
		return cls.getMethod(name, valcls);
	}

	public static String getShortName(String className) {
		if (StringUtils.empty(className)) {
			throw new IllegalArgumentException(
					"The class name must not be empty");
		}
		char[] chars = className.toCharArray();
		int lastDot = 0;
		for (int i = 0; i < chars.length; i++) {
			if (chars[i] == '.') {
				lastDot = i + 1;
			} else if (chars[i] == '$') { // handle
				// inner classes
				chars[i] = '.';
			}
		}
		return new String(chars, lastDot, chars.length - lastDot);
	}

	public static String getShortName(Class cls) {
		if (cls == null)
			return null;
		return getShortName(cls.getName());
	}

	public static Class toClass(Type type) {
		if (type instanceof Class) {
			return (Class) type;
		}
		if (type instanceof ParameterizedType) {
			return toClass(((ParameterizedType) type).getRawType());
		}
		return null;
	}

	public static String getResourceName(Class cls) {
		return getResourceName(cls, null);
	}

	public static String getResourceName(Class cls, String ext) {
		String name = cls.getName();
		name = name.replace('.', '/');
		if (ext != null)
			name += ext;
		return name;
	}

	public static String getClassPackageResourceName(Class clsPackage,
			String resourceName) {
		String name = clsPackage.getPackage().getName();
		name = name.replace('.', '/');
		return name + "/" + resourceName;
	}

	public static String[] listPackageClass(String packageName)
			throws Exception {

		String name = new String(packageName);
		if (!name.startsWith("/")) {
			// name = "/" + name;
		}

		name = name.replace('.', '/');

		// Get a File object for the package
		URL url = Thread.currentThread().getContextClassLoader()
				.getResource(name);
		String path = URLDecoder.decode(url.getFile(), "UTF-8");
		File directory = new File(path);

		if (!directory.exists()) {
			return new String[0];
		}

		// Get the list of the files contained in the package
		List<String> r = new LinkedList<String>();
		String[] files = directory.list();
		for (String file : files) {
			// we are only interested in .class files
			if (file.endsWith(".class")) {
				// removes the .class extension
				String classname = file.substring(0,
						file.length() - ".class".length());
				r.add(packageName + "." + classname);
			}
		}
		return r.toArray(new String[0]);

	}

	public static URL getResource(String res) {
		return getClassLoader().getResource(res);
	}

	/**
	 * 是否抽象类
	 * 
	 * @param cls
	 *            要进行判断的类
	 * @return
	 */
	public static boolean isAbstract(Class cls) {
		if (cls.isInterface())
			return true;
		if (Modifier.isAbstract(cls.getModifiers()))
			return true;
		if (cls.isEnum())
			return true;
		if (cls.isAnnotation())
			return true;
		return false;
	}

	/**
	 * 根据属性得到某对象中该属性的值
	 * 
	 * @param obj
	 *            要得到值的对象
	 * @param f
	 *            要得到值的属性
	 * @return
	 */
	public static Object getFieldValue(Object obj, Field f) {
		if (f == null) {
			return null;
		}
		Object ret = null;
		boolean b = f.isAccessible();
		f.setAccessible(true);
		try {
			ret = f.get(obj);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} finally {
			f.setAccessible(b);
		}

		return ret;
	}

	/**
	 * 根据属性设置某对象中该属性的值
	 * 
	 * @param obj
	 *            要设置值的对象
	 * @param f
	 *            要设置值的属性
	 * @param value
	 *            要设置的值
	 * @return
	 */
	public static void setFieldValue(Object obj, Field f, Object value) {
		if (obj == null || f == null) {
			return;
		}
		boolean b = f.isAccessible();
		f.setAccessible(true);
		try {
			f.set(obj, value);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} finally {
			f.setAccessible(b);
		}
	}

	public static void setFieldValueByString(Object obj, Field f, String value) {
		if (obj == null || f == null) {
			return;
		}
		boolean b = f.isAccessible();
		f.setAccessible(true);
		try {
			Object o = ConvertUtils.convert(value, f.getType());
			f.set(obj, o);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} finally {
			f.setAccessible(b);
		}
	}

	/**
	 * 根据属性设置某对象中该属性的值
	 * 
	 * @param obj
	 *            要设置值的对象
	 * @param fieldName
	 *            要设置值的属性的名称
	 * @param value
	 *            要设置的值
	 * @return
	 */
	public static void setFieldValue(Object obj, String fieldName, Object value) {
		Field f = getField(obj.getClass(), fieldName, null);
		if (f != null) {
			setFieldValue(obj, f, value);
		}
	}

	/**
	 * 根据属性得到某对象中该属性的值
	 * 
	 * @param obj
	 *            要得到值的对象
	 * @param fieldName
	 *            要得到值的属性名
	 * @param retValueType
	 *            返回值的类型
	 * @return
	 */
	public static <T> T getFieldValue(Object obj, String fieldName,
			Class<T> retValueType) {
		Field f = getField(obj.getClass(), fieldName, null);
		if (f == null) {
			return null;
		}

		return retValueType.cast(getFieldValue(obj, f));
	}

	/**
	 * 根据属性得到某对象中该属性的值
	 * 
	 * @param obj
	 *            要得到值的对象
	 * @param fieldName
	 *            要得到值的属性名
	 * @param retValueType
	 *            返回值的类型
	 * @return
	 */
	public static <T> T getFieldValue(Object obj, Field field,
			Class<T> retValueType) {
		return retValueType.cast(getFieldValue(obj, field));
	}

	/**
	 * 根据属性得到某对象中该属性的值
	 * 
	 * @param obj
	 *            要得到值的对象
	 * @param fieldName
	 *            要得到值的属性名
	 * @return
	 */
	public static Object getFieldValue(Object obj, String fieldName) {
		return getFieldValue(obj, fieldName, Object.class);
	}

	public static <T> T newIntance(Class<T> cls) {
		try {
			return cls.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public static Object newIntance(String className) {
		try {
			Class<?> cls = null;
			cls = forName(className);
			return cls.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 根据默认构造函数创建对象
	 * 
	 * @return
	 */
	public static <T> T newIntance(Class<T> classType, String className) {
		try {
			return classType.cast(forName(className).newInstance());
		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	/**
	 * 得到某类型中的所有的属性(包含父类)
	 * 
	 * @param cls
	 *            类型
	 * @return
	 */
	public static List<Field> getAllDeclaredFields(Class cls) {
		List<Field> allField = new ArrayList<Field>();
		List<Class<?>> classes = ClassUtils.getAllSuperclasses(cls);
		classes.add(cls);
		if (CollectionUtils.notEmpty(classes)) {
			for (Class c : classes) {
				allField.addAll(Arrays.asList(c.getDeclaredFields()));
			}
		}
		return allField;
	}

	/**
	 * 得到某类型中的所有的方法(包含父类)
	 * 
	 * @param cls
	 *            类型
	 * @return
	 */
	public static List<Method> getAllDeclaredMethod(Class cls) {
		List<Method> allField = new ArrayList<Method>();
		List<Class<?>> classes = ClassUtils.getAllSuperclasses(cls);
		classes.add(cls);
		if (CollectionUtils.notEmpty(classes)) {
			for (Class c : classes) {
				allField.addAll(Arrays.asList(c.getDeclaredMethods()));
			}
		}
		return allField;
	}

	/**
	 * 调用一个对象的方法(强行调用,私有方法也可以调用)
	 * 
	 * @param <T>
	 *            返回类型的泛型
	 * @param targetObj
	 *            调用的对象
	 * @param methodName
	 *            调用的方法名
	 * @param retType
	 *            调用方法的返回类型
	 * @param argsTypes
	 *            调用方法的参数的类型
	 * @param args
	 *            调用访求的参数
	 * @return
	 */
	public static <T> T invokeMethodForce(Object targetObj, String methodName,
			Class<T> retType, Class[] argsTypes, Object[] args) {
		if (targetObj == null) {
			return null;
		}

		Method m = lookupMethod(targetObj.getClass(), methodName, retType,
				argsTypes, true);
		if (m == null) {
			return null;
		}

		boolean b = m.isAccessible();
		m.setAccessible(true);
		try {
			return retType.cast(m.invoke(targetObj, args));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			m.setAccessible(b);
		}
		return null;
	}

	public static <T> T invokeMethodForce(Object targetObj, String methodName,
			Class<T> retType, Object[] args) {
		return invokeMethodForce(targetObj, methodName, retType, null, args);
	}

	public static <T> T invokeMethodForce(Object targetObj, String methodName,
			Class<T> retType) {
		return invokeMethodForce(targetObj, methodName, retType, null);
	}

	public static Object invokeMethodForce(Object targetObj, String methodName,
			Object[] args) {
		return invokeMethodForce(targetObj, methodName, Object.class, null,
				args);
	}

	public static Object invokeMethodForce(Object targetObj, String methodName) {
		return invokeMethodForce(targetObj, methodName, Object.class);
	}

	/**
	 * 用el表达式设置一个对象的值.如果对象中有对象时,会自动创建新的对象(使用默认的构造函数进行创建对象)<BR>
	 * 用法:<BR>
	 * setFieldValueByEL('a.b.name',new A(),"ronald")<BR>
	 * 最后:A对象中的B会被自动创建对象,b中的name的值为ronald字符串
	 * 
	 * @param expression
	 *            表达式(参考ognl)
	 * @param target
	 *            要设置值的对象
	 * @param value
	 *            要进行设置的值
	 * @return
	 */
	public static <T> T setFieldValueByEL(String expression, T target,
			Object value) {
		if (target == null || expression == null) {
			return null;
		}

		OgnlRuntime.setNullHandler(Object.class, new CreateObjectNullHandler());
		try {
			Ognl.setValue(expression, target, value);
		} catch (OgnlException e) {
			e.printStackTrace();
		}
		return target;
	}

	public static void setFieldValueByEL(Map<String, Object> context,
			Object target) {
		if (context != null && target != null) {
			for (String key : context.keySet()) {
				setFieldValueByEL(key, target, context.get(key));
			}
		}
	}

	/**
	 * 用el表达式得到一个对象的值<BR>
	 * 用法:<BR>
	 * A a = new A();<BR>
	 * B b = new B();<BR>
	 * b.setName("name");<BR>
	 * a.setB(b);<BR>
	 * getFieldValueByEL('a.b.name',a,String.class)<BR>
	 * 得到的值为"name"字符串
	 * 
	 * @param expression
	 *            表达式(参考ognl)
	 * @param target
	 *            要得到值的对象
	 * @param retType
	 *            要得到的值的类型
	 * @return
	 */
	public static <T> T getFieldValueByEL(String expression, Object target,
			Class<T> retType) {
		try {
			return retType.cast(Ognl.getValue(expression, target));
		} catch (OgnlException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Collection<String> getShortNameFromCollection(
			Collection<Class<?>> classes) {
		Collection<String> col = new ArrayList<String>();
		if (CollectionUtils.notEmpty(classes)) {
			for (Class cls : classes) {
				col.add(getShortName(cls));
			}
		}
		return col;
	}

	public static InputStream getResourceAsStream(String res) {
		return getClassLoader().getResourceAsStream(res);
	}

	public static InputStream getResourceAsStream(String res,
			ClassLoader classLoader) {
		if (classLoader == null) {
			return getResourceAsStream(res);
		}
		return classLoader.getResourceAsStream(res);
	}

	/**
	 * 得到某类中的属性(包含父类中的属性)
	 * 
	 * @param clazz
	 *            要进行查找的类
	 * @param fieldName
	 *            属性名
	 * @return
	 */
	public static Field getField(Class clazz, String fieldName) {
		return getField(clazz, fieldName, null);
	}

	/**
	 * 当要设置的值的对象为空时,自动创建新的对象
	 * 
	 * @author ronald
	 * @date 2008-5-8
	 */
	private static class CreateObjectNullHandler implements NullHandler {

		private static final Log log = LogFactory
				.getLog(CreateObjectNullHandler.class);

		public Object nullMethodResult(Map context, Object target,
				String methodName, Object[] args) {
			return null;
		}

		public Object nullPropertyValue(Map context, Object target,
				Object property) {
			if ((target == null) || (property == null)) {
				return null;
			}

			try {
				String propName = property.toString();
				Object realTarget = null;
				// OgnlUtil.getRealTarget(propName, context,
				// target);
				Class clazz = null;

				if (realTarget != null) {
					PropertyDescriptor pd = OgnlRuntime.getPropertyDescriptor(
							realTarget.getClass(), propName);
					if (pd == null) {
						return null;
					}

					clazz = pd.getPropertyType();
				}

				if (clazz == null) {
					return null;
				}

				Object param = createObject(clazz, realTarget, propName,
						context);

				Ognl.setValue(propName, context, realTarget, param);

				return param;
			} catch (Exception e) {
				log.error("", e);
			}

			return null;
		}

		private Object createObject(Class clazz, Object target,
				String property, Map context) throws Exception {
			if (Collection.class.isAssignableFrom(clazz)) {
				return new ArrayList();
			} else if (clazz == Map.class) {
				return new HashMap();
			}

			return clazz.newInstance();
		}
	}

	/**
	 * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>
	 * 
	 * @param clazz
	 *            clazz 需要反射的类,该类必须继承范型父类
	 * @param index
	 *            泛型参数所在索引,从0开始.
	 * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口，即不支持泛型，所以直接返回
	 *         <code>Object.class</code>
	 */
	@SuppressWarnings("unchecked")
	public static Class getSuperClassGenricType(Class clazz, int index) {
		Type genType = clazz.getGenericSuperclass();// 得到泛型父类
		// 如果没有实现ParameterizedType接口，即不支持泛型，直接返回Object.class
		if (!(genType instanceof ParameterizedType)) {
			return Object.class;
		}
		// 返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends
		// DaoSupport<Buyer,Contact>就返回Buyer和Contact类型
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		if (index >= params.length || index < 0) {
			throw new RuntimeException("你输入的索引"
					+ (index < 0 ? "不能小于0" : "超出了参数的总数"));
		}
		if (!(params[index] instanceof Class)) {
			return Object.class;
		}
		return (Class) params[index];
	}
}